Skip to content

mod_charset_lite: bound ctx->buf writes in finish_partial_char - #679

Closed
arshsmith1 wants to merge 1 commit into
apache:trunkfrom
arshsmith1:charset-lite-partial-char-bound
Closed

arshsmith1 wants to merge 1 commit into
apache:trunkfrom
arshsmith1:charset-lite-partial-char-bound

Conversation

@arshsmith1

Copy link
Copy Markdown
  1. set_aside_partial_char stops once a straddling char reaches sizeof(ctx->buf) (FATTEST_CHAR) and flags EES_LIMIT, but finish_partial_char appends to ctx->buf[ctx->saved] with no such limit.
  2. if apr_xlate_conv_buffer keeps returning APR_INCOMPLETE while input remains, ctx->saved grows past the 8-byte buffer and the next write lands out of bounds.

Added the sizeof(ctx->buf) bound to the loop so an over-wide char takes the existing EES_LIMIT path, the same way set_aside_partial_char already refuses one.

@arshsmith1

Copy link
Copy Markdown
Author

any update?

@vikk777

vikk777 commented Oct 1, 2026 •

Copy link
Copy Markdown

Stacktrace of SEGV:

==190932==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x560b94bb5549 bp 0x7ffd8ef65f50 sp 0x7ffd8ef65e60 T0)
==190932==The signal is caused by a READ memory access.
==190932==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x560b94bb5549 in xlate_in_filter /httpd/modules/filters/mod_charset_lite.c:1060:13
    #1 0x560b948b1061 in ap_get_brigade /httpd/server/util_filter.c:553:16
    #2 0x560b94c69e9a in ap_discard_request_body /httpd/modules/http/http_filters.c:1648:14
    #3 0x560b94923220 in default_handler /httpd/server/core.c:4916:22
    #4 0x560b9483dd89 in ap_run_handler /httpd/server/config.c:169:1
    #5 0x560b9483f98d in ap_invoke_handler /httpd/server/config.c:443:14
    #6 0x560b94c3f9a3 in ap_process_async_request /httpd/modules/http/http_request.c:452:29
    #7 0x560b94c3fee2 in ap_process_request /httpd/modules/http/http_request.c:487:5
    #8 0x560b94c289ee in ap_process_http_sync_connection /httpd/modules/http/http_core.c:208:13
    #9 0x560b94c27288 in ap_process_http_connection /httpd/modules/http/http_core.c:249:16
    #10 0x560b9489e319 in ap_run_process_connection /httpd/server/connection.c:42:1
    #11 0x560b9483a992 in fuzz_one_input /httpd/fuzz/fuzz_common.c:747:9
    #12 0x560b948343f5 in main /httpd/fuzz/mod_fuzzy_proto_charset.cc:45:5
    #13 0x7f674b7d1249 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #14 0x7f674b7d1304 in __libc_start_main csu/../csu/libc-start.c:360:3
    #15 0x560b9474d220 in _start (/httpd/mod_fuzzy_proto_charset+0x246220) (BuildId: 6418c14307b02cd8fa3b72b4483ad9edb29dcf31)

==190932==Register values:
rax = 0x0363636363636365  rbx = 0x00007ffd8ef65e60  rcx = 0x00000a4a00019f7d  rdx = 0x5663d88faf63c600  
rdi = 0x1b1b1b1b1b1b1b2b  rsi = 0x0000000000000002  rbp = 0x00007ffd8ef65f50  rsp = 0x00007ffd8ef65e60  
 r8 = 0x00000fed68f58d80   r9 = 0x00005250000cfc27  r10 = 0x00000a4a00019f84  r11 = 0x00000a4a80011f78  
r12 = 0x00007f6747a076c0  r13 = 0x0000560b95d8b870  r14 = 0x00007f6747a076a0  r15 = 0x00007f6747a07680

Input request:

00000000: 5055 5420 2f63 6e20 4854 5450 2f31 2e31  PUT /cn HTTP/1.1
00000010: 0d0a 486f 7374 3a20 6c6f 6361 6c68 6f73  ..Host: localhos
00000020: 740d 0a54 7261 6e73 6665 722d 456e 636f  t..Transfer-Enco
00000030: 6469 6e67 3a20 6368 756e 6b65 640d 0a0d  ding: chunked...
00000040: 0a31 0d0a 1b0d 0a31 3030 0d0a 1b1b 1b1b  .1.....100......
00000050: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000060: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000070: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000080: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000090: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000a0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000b0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000c0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000d0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000e0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
000000f0: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000100: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000110: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000120: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000130: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b  ................
00000140: 1b1b 1b1b 1b1b 1b1b 1b1b 1b1b 0d0a 300d  ..............0.
00000150: 0a0d 0a                                  ...

config file:

ServerName localhost:80
Timeout 2
HttpProtocolOptions Unsafe
DocumentRoot "/tmp/htdocs"
ErrorLog "/dev/stdout"
LogLevel emerg
# TypesConfig conf/mime.types

<Directory "/">
    Require all granted
</Directory>

<Location "/jp">
    CharsetSourceEnc UTF-8
    CharsetDefault ISO-2022-JP
    SetInputFilter XLATEIN
</Location>

<Location "/jp2">
    CharsetSourceEnc UTF-8
    CharsetDefault ISO-2022-JP-2
    SetInputFilter XLATEIN
</Location>

<Location "/kr">
    CharsetSourceEnc UTF-8
    CharsetDefault ISO-2022-KR
    SetInputFilter XLATEIN
</Location>

<Location "/cn">
    CharsetSourceEnc UTF-8
    CharsetDefault ISO-2022-CN-EXT
    SetInputFilter XLATEIN
</Location>

LimitRequestFieldSize 100000
LimitRequestLine 100000

@arshsmith1

Copy link
Copy Markdown
Author

Thanks for the repro, @vikk777. That lines up with what this PR was about: the ESC run under ISO-2022-CN-EXT keeps apr_xlate_conv_buffer at APR_INCOMPLETE, so ctx->saved walks past the 8-byte ctx->buf and corrupts the adjacent ctx state, which is what blows up later at xlate_in_filter:1060.

Looks like this already landed in trunk as 90a4f36 ("handle incomplete char"), which caps the loop at sizeof(ctx->buf) and takes the EES_LIMIT path, the same bound this PR proposed. Glad it's fixed.

@notroj

notroj commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Thanks, yes this was tracked as CVE-2026-56153). A pyhttpd test would be welcome here, if that's feasible, I can't see we added any coverage for this.

@notroj notroj closed this Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants